/*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(NICTA_BSD)
 */

#ifndef _MEM_LAYOUT_H_
#define _MEM_LAYOUT_H_

/* Various useful macros */
#define PAGE_BITS          (12)
#define PAGE_SIZE          (1 << PAGE_BITS)
#define PAGE_MASK          ((PAGE_SIZE) - 1)
#define PAGE_SHIFT(X)      ((X) >> PAGE_BITS)
#define PAGE_UNSHIFT(X)    ((X) << PAGE_BITS)
#define PAGE_ALIGN(X)      (PAGE_UNSHIFT(PAGE_SHIFT(X)))
#define PAGE_IS_ALIGNED(X) (!((X) & (PAGE_SIZE - 1)))
#define PAGE_REMAINING(X)  (PAGE_SIZE - ((X) & PAGE_MASK))

/* An artificial limit on how many physical frames can be used. */
/* Tweak this to induce artificial memory pressure. */
/* Best performance when set somewhere below 512MiB -
   the extra frames are considered reserved for page directories etc */
#define PHYS_MAX_FRAMES (0x15000)
// #define PHYS_MAX_FRAMES (60)


/* Address where memory used for DMA starts getting mapped.
 * Do not use the address range between DMA_VSTART and DMA_VEND */
#define DMA_VSTART            (0x10000000)
#define DMA_SIZE_BITS         (22)
#define DMA_VEND              (DMA_VSTART + (1ull << DMA_SIZE_BITS))

/* Amount of memory reserved for the frame table */
#define FRAME_TABLE_SIZE_BITS (25) // 32MiB
#define FRAME_TABLE_SIZE      (1 << FRAME_TABLE_SIZE_BITS)
#define FRAME_TABLE_START     (WINDOW_START - FRAME_TABLE_SIZE)

/* Filename for the swap file */
#define SWAP_FILE_NAME        "swapfile"

/* Memory reserved for the swap table, beneath the frame table */
/* (The swap table is used for selecting swap numbers) */
#define SWAP_TABLE_SIZE_BITS  (21) // 2MiB
#define SWAP_TABLE_SIZE       (1 << SWAP_TABLE_SIZE_BITS)
#define SWAP_TABLE_START      (FRAME_TABLE_START - SWAP_TABLE_SIZE)

/* Memory reserved for swapfile metadata. Used to remap frames on swapin. */
#define SWAP_META_SIZE_BITS   (26) // 64MiB
#define SWAP_META_SIZE        (1 << SWAP_META_SIZE_BITS)
#define SWAP_META_START       (SWAP_TABLE_START - SWAP_META_SIZE)

/* The reserved range for mapping physical memory into SOS */
#define WINDOW_START          (0x20000000)
#define WINDOW_END            (0x60000000)

/* From this address onwards is where any devices will get mapped in
 * by the map_device function. You should not use any addresses beyond
 * here without first modifying map_device */
#define DEVICE_START          (0xB0000000)
#define ROOT_VSTART           (0xC0000000)

/* SOS process address space constants */
#define SOS_PROCESS_ELF_BOTTOM   (0x00000000)
#define SOS_PROCESS_ELF_TOP      (0x1FFFE000)
#define SOS_PROCESS_IPC_BUFFER   (0xDFFFE000)
#define SOS_PROCESS_IPC_GUARD    (0xDFFFD000)
#define SOS_PROCESS_STACK_TOP    (0x90000000)
/* The stack is statically bounded, for now */
#define SOS_PROCESS_STACK_BOTTOM (0x8FF00000)
#define SOS_PROCESS_STACK_GUARD  (0x8FEFF000)
/* XXX M4: Real brk syscall, allowing arbitrary ELF sizes */
#define SOS_PROCESS_HEAP_GUARD   (0x1FFFF000)
#define SOS_PROCESS_HEAP_START   (0x20000000)
#define SOS_PROCESS_BRK          (0x20100000)

#endif /* _MEM_LAYOUT_H_ */
